/**
 * StkDelayLine
 * <p/>
 * User: joakimd
 * Date: 2013-03-11
 * Time: 17:08
 */
package org.dru.stk {
public final class StkDelay {
    private var _capacity: int;
    private var _duration: Number;
    private var _buffer: Vector.<Number>;
    private var _idxMask: int;
    private var _writeIdx: int;
    private var _readIdx: int;
    private var _fraction: Number;
    private var _current: Number;

    public function StkDelay(capacity: int = 44100.0, duration: Number = 441.0) {
        _capacity = -1;
        _duration = 0.0;
        setCapacity(capacity);
        setDuration(duration);
    }

    public function setCapacity(value: int): void {
        const capacity: int = StkMath.roundUpNearestPow2(value);
        if (capacity != _capacity) {
            _capacity = capacity;
            _idxMask = capacity - 1;
            _buffer = new Vector.<Number>(capacity, true);
            _writeIdx = 0;
            _current = 0.0;
            update();
        }
    }

    public function setDuration(value: Number): void {
        if (value != _duration) {
            _duration = value;
            update();
        }
    }

    private function update(): void {
        const dur: Number = (_duration > _capacity ? _capacity : _duration);
        var readPos: Number = Number(_writeIdx) - _duration;
        if (readPos < 0.0) {
            readPos += Number(_capacity);
        }
        _readIdx = int(readPos);
        _fraction = readPos - Number(_readIdx);
    }

    public function current(): Number {
        return _current;
    }

    public function next(src: Number): Number {
        const tmp1: Number = _buffer[_readIdx];
        _readIdx = (_readIdx + 1) & _idxMask;
        const tmp2: Number = _buffer[_readIdx];
        _buffer[_writeIdx] = src;
        _writeIdx = (_writeIdx + 1) & _idxMask;
        return _current = tmp1 + (tmp2 - tmp1) * _fraction;
    }
}
}
